let str:string = 'hello'

console.log('str', str)

interface Person { name: string, age: 18 }
let obj: Person = { name: "张三", age: 18 }

// 联合类型
let obj2: string | object | number = 'hello'
interface Human { name: string; age: number }
interface Car { money: number }
type Obj = Human | Car
let obj4: Obj = { name: "张三", money: 100 }
console.log(`obj4, name: ${(obj4 as Human).name}, money: ${(obj4 as Car).money}`)

// 交叉类型
type Obj1 = { name: string }
type Obj2 = { age: number }
let obj3: Obj1 & Obj2 = { name: '张三', age: 5 }

// 字面量数据类型
type paramFlag = null | 0 | 1
let  n1:paramFlag = 1

// never类型的意义
// 某个方法，穷尽了参数中的所有可接收的类型时，使用 never 避免未来扩展新的类型，没有对应类型的实现。
type param1 = number | string
function say(value: param1) {
  if (typeof value === 'string') {

  }else if (typeof value === 'number') {

  } else {
    // 此时data就是never类型，如果未来参数扩展出新的类型，type param1 = number | string | boolean，那么data就是那个新的类型
    let data = value  
  }
}
say(1)

// 枚举的意义
const Status = { NO_ADUIT: 0, ADUIT_SUCCESS: 1, ADUIT_FAIL: 2 }
// status类型为number，太宽泛了，不利于后期代码阅读，与项目维护
// 此时，枚举就能明确的约束status的类型
class MyAduit {
  getAduitStatus(status: number) {
    if (status === Status.NO_ADUIT) {
      console.log('尚未审核')
    } else if (status === Status.ADUIT_SUCCESS) {
      console.log('审核成功')
    } else if (status === Status.ADUIT_FAIL) {
      console.log('审核失败')
    }
  }
}

enum Week {
  Monday = 1,
  Tuseday,
  Wensday,
  Thirsday,
  Friday
}
// 枚举有双重映射，可以由key到值，也可以由值到key
console.log(Week.Monday)
console.log(Week["Monday"])
console.log(Week[1])
console.log(Week[3])
enum Weekend {
  Monday = "MyMonday",
  Tuseday = "Tuseday",
  Wensday = "Wensday",
}
// console.log(Weekend["MyMonday"])  // 会报错
class MyAduit2 {
  getAduitStatus(status: Week): void {
    if (status === Status.NO_ADUIT) {
      console.log('尚未审核')
    } else if (status === Status.ADUIT_SUCCESS) {
      console.log('审核成功')
    } else if (status === Status.ADUIT_FAIL) {
      console.log('审核失败')
    }
  }
}
type Book = { name: string, price: number }
let str2:number = 1
let strData: any = str2
let book:Book[] = strData
let n2:unknown = { name: 'zhangsan' }
let n3:any = n2
// console.log(n2.name)  // unknown类型的变量，不能获取任何属性与方法，不然会报错

// null与undefined
let str3: any = undefined
let str4: any = null
function sayHello(str?:string) {
  if (str) console.log(str.toString())
}
sayHello()